home *** CD-ROM | disk | FTP | other *** search
/ C/C++ Users Group Library 1996 July / C-C++ Users Group Library July 1996.iso / vol_100 / 167_01 / prep.c < prev    next >
Text File  |  1985-08-19  |  7KB  |  308 lines

  1. /*
  2. HEADER:     CUG
  3. TITLE:        PREP.C - Prepare Text for Statistical Processing
  4. VERSION:    1.00
  5. DATE:        11/03/85
  6. DESCRIPTION:    "PREP is a full emulation of Unix's 'prep'
  7.         utility. It reads each text file given on the
  8.         command line in sequence and writes it on the
  9.         standard output, one word to a line."
  10. KEYWORDS:    UNIX
  11. SYSTEM:        ANY
  12. FILENAME:    PREP.C
  13. WARNINGS:    NONE
  14. CRC:        xxxx
  15. SEE-ALSO:    NONE
  16. AUTHORS:    Ian Ashdown - byHeart Software
  17. COMPILERS:    ANY
  18. REFERENCES:    AUTHORS: Bell Laboratories
  19.         TITLE:     UNIX Programmer's Manual, Volume 1
  20.              p. 109; Holt, Rinehart and Winston
  21. ENDREF
  22. */
  23.  
  24. /*-------------------------------------------------------------*/
  25.  
  26. /* PREP.C - Prepare Text for Statistical Processing
  27.  *
  28.  * Version 1.00        November 3rd, 1985
  29.  *
  30.  * Copyright 1985:    Ian Ashdown
  31.  *            byHeart Software
  32.  *            1089 West 21st Street
  33.  *            North Vancouver, B.C. V7P 2C6
  34.  *            Canada
  35.  *
  36.  * This program may be copied for personal, non-commercial use
  37.  * only, provided that the above copyright notice is included in
  38.  * all copies of the source code. Copying for any other use
  39.  * without previously obtaining the written permission of the
  40.  * author is prohibited.
  41.  *
  42.  * Synopsis:    PREP [-diop] [file] ...
  43.  *
  44.  * Description:    PREP reads each file given by the command line
  45.  *        in sequence (or standard input if no files are
  46.  *        specified) and writes it on the standard output,
  47.  *        one word at a time. (A "word" is defined as a
  48.  *        string of alphabetic characters and imbedded or
  49.  *        (one singular) trailing apostrophes, delimited by
  50.  *        space or punctuation.) Hyphenated words are
  51.  *        broken apart unless the hyphens occur at the end
  52.  *        of a line; then the hyphen is removed and the two
  53.  *        parts of the word concatenated. All other
  54.  *        characters are normally discarded.
  55.  *
  56.  *        The following options may appear in any order on
  57.  *        the command line. The -i and -o options must
  58.  *        immediately precede their associated filenames.
  59.  *
  60.  *        -d    Precede each word on the standard output
  61.  *            with its number. Words are numbered
  62.  *            sequentially as they are found in the
  63.  *            files.
  64.  *        -i    Ignore the next file by not sending the
  65.  *            words found to the standard output. (The
  66.  *            word count displayed by the -d option,
  67.  *            however, will nevertheless be incremented
  68.  *            as each word is found.)
  69.  *        -o    Only the words found in the next file
  70.  *            will appear on the standard output. All
  71.  *            words found in other files will be
  72.  *            counted for the -d option.
  73.  *        -p    Include punctuation characters (any
  74.  *            nonalphanumeric printable character) as
  75.  *            separate output lines. The punctuation
  76.  *            characters are not counted for the -d
  77.  *            option.
  78.  *
  79.  * Bugs:    A "word" is defined as consisting of a maximum of
  80.  *        alphabetic 256 characters and imbedded or (one
  81.  *        singular) trailing apostrophes.
  82.  *
  83.  * (Note: the above description is a reworded and expanded
  84.  *      version of that appearing in the "UNIX Programmer's
  85.  *      Manual", copyright 1979, 1983 Bell Laboratories.)
  86.  */
  87.  
  88. /*** Definitions ***/
  89.  
  90. #define FALSE         0
  91. #define TRUE         1
  92.  
  93. #define FIL_ERR      0    /* Error codes */
  94. #define ILL_OPT         1
  95. #define REP_OPT      2
  96.  
  97. #define MAXWORD    256    /* Maximum size of "word" */
  98.  
  99. /*** Typedefs ***/
  100.  
  101. typedef int BOOL;    /* Boolean flag */
  102.  
  103. /*** Global Variables ***/
  104.  
  105. long word_cnt = 0L;    /* Word count */
  106. BOOL dflag = FALSE,    /* Command line option flags */
  107.      fflag = FALSE,
  108.      iflag = FALSE,
  109.      oflag = FALSE,
  110.      pflag = FALSE,
  111.      sflag = FALSE;
  112.  
  113. /*** Include Files ***/
  114.  
  115. #include <stdio.h>
  116. #include <ctype.h>
  117.  
  118. /*** Main Body of Program ***/
  119.  
  120. int main(argc,argv)
  121. int argc;
  122. char **argv;
  123. {
  124.   int arg_count = argc;
  125.   char *s,
  126.        **arg_vector = argv;
  127.   void proc_file(),
  128.        error();
  129.  
  130.   /* Parse the command line for user-selected global options */
  131.  
  132.   while(--arg_count)
  133.   {
  134.     if((*++arg_vector)[0] == '-')
  135.       for(s = arg_vector[0] + 1; *s != '\0'; s++)
  136.     switch(toupper(*s))
  137.     {
  138.       case 'D':
  139.         dflag = TRUE;
  140.         break;
  141.       case 'I':    /* Ignore this option on first pass */
  142.         break;
  143.       case 'O':    /* Suppress all files but -o option */
  144.         if(sflag == TRUE)
  145.           error(REP_OPT,NULL);
  146.         else
  147.           sflag = TRUE;
  148.         break;
  149.       case 'P':
  150.         pflag = TRUE;
  151.         break;
  152.       default:
  153.         error(ILL_OPT,*arg_vector);
  154.     }
  155.   }
  156.  
  157.   /* Process the files */
  158.  
  159.   while(--argc)
  160.   {
  161.     if((*++argv)[0] == '-')
  162.       for(s = argv[0] + 1; *s != '\0'; s++)
  163.     switch(toupper(*s))
  164.     {
  165.       case 'D':
  166.       case 'P':
  167.         break;
  168.       case 'I':
  169.         iflag = TRUE;
  170.         break;
  171.       case 'O':
  172.         oflag = TRUE;
  173.         break;
  174.       default:
  175.         break;
  176.     }
  177.     else
  178.     {
  179.       fflag = TRUE;
  180.       proc_file(*argv);
  181.       iflag = FALSE;
  182.       oflag = FALSE;
  183.     }
  184.   }
  185.   if(fflag == FALSE)
  186.     proc_file(NULL);
  187. }
  188.  
  189. /*** Functions ***/
  190.  
  191. /* PROC_FILE() */
  192.  
  193. void proc_file(fname)
  194. char *fname;
  195. {
  196.   char word[MAXWORD+1];
  197.   int c,
  198.       getword();
  199.   FILE *fp,
  200.        *freopen();
  201.   void error();
  202.  
  203.   /* Open input file (if specified) */
  204.  
  205.   if(fname)
  206.     if((fp = freopen(fname,"r",stdin)) == NULL)
  207.       error(FIL_ERR,fname);
  208.  
  209.   /* Output words in accordance with user-selected options */
  210.  
  211.   do
  212.   {
  213.     c = getword(word);
  214.     if(*word)    /* Display the word (if any) */
  215.     {
  216.       word_cnt++;
  217.       if(iflag == FALSE && (sflag == FALSE || (sflag == TRUE &&
  218.       oflag == TRUE)))
  219.       {
  220.     if(dflag == TRUE)
  221.       printf("%05ld: ",word_cnt);
  222.     puts(word);
  223.       }
  224.     }
  225.     if(pflag == TRUE)    /* Display any punctuation */
  226.       if(ispunct(c))
  227.       {
  228.     putchar(c);
  229.     putchar('\n');
  230.       }
  231.   }
  232.   while(c != EOF);
  233. }
  234.  
  235. /* GETWORD() - Gets next "word" from input. Leaves "word" found
  236.  *           (may be NULL) in array "word[]" and returns last
  237.  *           character obtained from standard input. Hyphens
  238.  *           followed by newlines are ignored, and "word" may
  239.  *           contain imbedded or (one singular) trailing
  240.  *           apostrophes. Size in characters limited to
  241.  *           MAXWORD.
  242.  */
  243.  
  244. int getword(word)
  245. char *word;
  246. {
  247.   int c,
  248.       limit = MAXWORD;
  249.   BOOL aflag = FALSE;
  250.  
  251.   while(limit)
  252.   {
  253.     c = getchar();
  254.     if(c == '-')    /* Hyphen at end of line? */
  255.     {
  256.       c = getchar();
  257.       if(c == '\n')
  258.     continue;
  259.       else
  260.         break;
  261.     }
  262.     else if(c == '\'')    /* Imbedded or trailing apostrophe? */
  263.     {
  264.       if(aflag == TRUE || limit == MAXWORD)
  265.     break;
  266.       aflag = TRUE;
  267.     }
  268.     else if(!isalpha(c))
  269.       break;
  270.     *word++ = c;    /* Add character to word */
  271.     limit--;
  272.   }
  273.   *word = '\0';        /* Terminate word string */
  274.   return c;
  275. }
  276.  
  277. /* ERROR() - Error reporting. Returns an exit status of 2 to the
  278.  *         parent process.
  279.  */
  280.  
  281. void error(n,str)
  282. int n;
  283. char *str;
  284. {
  285.   fprintf(stderr,"\007\n*** ERROR - ");
  286.   switch(n)
  287.   {
  288.     case FIL_ERR:
  289.       fprintf(stderr,"Cannot open input file: %s",str);
  290.       break;
  291.     case ILL_OPT:
  292.       fprintf(stderr,"Illegal command line option: %s",str);
  293.       break;
  294.     case REP_OPT:
  295.       fprintf(stderr,"Repeated -o option");
  296.       break;
  297.     default:
  298.       break;
  299.   }
  300.   fprintf(stderr," ***\n\nUsage: prep [-diop] [file] ...\n");
  301.   exit(2);
  302. }
  303.  
  304. /*** End of PREP.C ***/
  305.  */
  306.     {
  307.       c = getchar();
  308.